package com.oc.mba.dao.impl;

import java.util.List;

import org.apache.commons.lang.ArrayUtils;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Query;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.oc.mba.dao.BaseDAOHibernate;
import com.oc.mba.dao.OcQuestionDAO;
import com.oc.mba.entity.OcPaperQuestion;
import com.oc.mba.entity.OcQuestion;
import com.oc.mba.entity.PagingModel;
import com.oc.mba.util.CommLog;
import com.oc.mba.util.PaginationSupport;

@Repository
public class OcQuestionDAOImpl extends BaseDAOHibernate implements OcQuestionDAO {

	private static final CommLog logger = new CommLog(OcQuestionDAOImpl.class);

	public List<OcQuestion> findByProperty(String propertyName, Object value) {
		logger.debug("finding OcQuestion instance with property: "
				+ propertyName + ", value: " + value);
		try {
			String queryString = "from OcQuestion as model where model."
					+ propertyName + "= ? order by model.id";
			return getHibernateTemplate().find(queryString, value);
		} catch (RuntimeException re) {
			logger.error("find by property name failed", re);
			throw re;
		}
	}

	@Override
	public OcQuestion findQuestion(Integer topicID) {
		List<OcQuestion> topicList = findByProperty("id", topicID);
		if (topicList != null && topicList.size() > 0) {
			return topicList.get(0);
		}
		return null;
	}

	@Override
	public List<OcQuestion> listAll() {
		logger.debug("finding OcQuestion list");
		try {
			String queryString = "from OcQuestion as model ";
			return getHibernateTemplate().find(queryString, null);
		} catch (RuntimeException re) {
			logger.error("find by property name failed", re);
			throw re;
		}
	}

	@Override
	public void save(OcQuestion question) {
		getHibernateTemplate().save(question);
	}

	@Override
	public void update(OcQuestion question) {
		getHibernateTemplate().update(question);
	}

	@Override
	public void deleteQuestion(Integer questionID, boolean real) {
		OcQuestion question = findQuestion(questionID);
		if (question != null) {
			if (!real) {
				getHibernateTemplate().delete(question);
			}
			else {
				// 逻辑删除
				question.setQuestionStatus((short)-1);
				update(question);
			}
		}
	}

	@Override
	public List<OcQuestion> findQuestionByIDs(List<Integer> questionIDs) {
		logger.info("finding OcQuestion by IDs instance with ids: " + ArrayUtils.toString(questionIDs));
		return getHibernateTemplate().findByNamedParam("from OcQuestion as model " + 
	              "where model.id in (:ids) ", "ids", questionIDs); 
	}

	@Override
	public List<OcQuestion> findQuestionBySerial(String serial) {
		
		String propertyName = "questionSerial";
		try {
			serial = "%" + serial + "%";
			
			String queryString = "from OcQuestion as model where model."
					+ propertyName + " like ? and model.questionStatus=1";
			
			logger.info("finding OcQuestion instance with property: " + propertyName + ", value: " + serial);
			return getHibernateTemplate().find(queryString, serial);
		} catch (RuntimeException re) {
			logger.error("find by property name failed", re);
			throw re;
		}
	}

//	@Override
//	public PagingModel<OcQuestion> listAllQuestionByPaging(int offset, int pageSize) {
//		//查询记录数 
//		String selectCountHql = "select count(*) from OcQuestion q ";
//		
//		// 总记录数
//		int total = ((Long) this.getSession().createQuery(selectCountHql).uniqueResult()).intValue();
//		logger.info("total:" + total);
//		
//		// 查询机构列表
//		String selectHql = "from OcQuestion q";
//		List<OcQuestion> list = this.getSession().createQuery(selectHql).setFirstResult(offset).setMaxResults(pageSize).list();
//		logger.info("listSize:" + list.size());
//		PagingModel<OcQuestion> pm = new PagingModel<OcQuestion>();
//		pm.setTotal(total);
//		pm.setList(list);
//		return pm;
//	}

	@Override
	public PaginationSupport listAllPublishQuestionForPaging(int pageSize, int current) {
		if (current < 1) {
			current = 1;
		}
		// 取得记录总数
		int totalCount = countAllPublishQuestion();
		int pageNumer = totalCount / pageSize;
		int redundant = totalCount % pageSize;
		if (redundant > 0) {
			pageNumer++;
		}
		
		if (current > pageNumer) {
			current = pageNumer;
		}
		
		// 取得所有记录
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(OcQuestion.class);
		detachedCriteria.add(Restrictions.or(
			        Restrictions.eq("questionStatus", Short.valueOf("0")),
			        Restrictions.eq("questionStatus", Short.valueOf("1"))
			    ));
		detachedCriteria.addOrder(Order.desc("id")); 
		detachedCriteria.setFetchMode("ocQuestionOptions", FetchMode.SELECT);  
		detachedCriteria.setFetchMode("ocQuestionTechniques", FetchMode.SELECT);  
		detachedCriteria.setFetchMode("ocQuestionSolutions", FetchMode.SELECT);  
		detachedCriteria.setFetchMode("ocQuestionSeckills", FetchMode.SELECT);  
		detachedCriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		List<OcQuestion> items = getHibernateTemplate().findByCriteria(detachedCriteria, pageSize * (current - 1), pageSize);
		return new PaginationSupport(items, totalCount, pageSize, (current - 1) * pageSize);
	}

	@Override
	public int countAllPublishQuestion() {
		logger.debug("finding publish state OcQuestion count");
		try {
			String queryString = "select count(*) from OcQuestion as model where model.questionStatus=0 or model.questionStatus=1 order by id desc";
			return ((Long) this.getSession().createQuery(queryString).uniqueResult()).intValue();
		} catch (RuntimeException re) {
			logger.error("find by property name failed", re);
			throw re;
		}
	}
	
	public static void main(String[] args) {
		int total = 101;
		int pageSize = 10;
		int pageNumer = total / pageSize;
		int redundant = total % pageSize;
		if (redundant > 0) {
			pageNumer++;
		}
		System.out.println("pageNumer=" + pageNumer + ", pageSize=" + pageSize + ", redundant=" + redundant);
	}
}
